package aqs;

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

public class MyLock {

    // 内部同步器类，继承 AQS
    private static class Sync extends AbstractQueuedSynchronizer {
        // 尝试获取锁，state == 0 表示未锁定
        @Override
        protected boolean tryAcquire(int acquires) {
            if (compareAndSetState(0, 1)) { // CAS 尝试将 state 由 0 设置为 1
                setExclusiveOwnerThread(Thread.currentThread()); // 设置当前线程为独占锁的持有者
                return true; // 成功获取锁
            }
            return false; // 获取锁失败
        }

        // 尝试释放锁，state == 1 表示锁定状态
        @Override
        protected boolean tryRelease(int releases) {
            if (getState() == 0) {
                throw new IllegalMonitorStateException(); // 非法状态（未持有锁却释放锁）
            }
            setExclusiveOwnerThread(null); // 清空当前线程的持有者标记
            setState(0); // 将 state 设置回 0
            return true; // 成功释放锁
        }

        @Override
        protected boolean isHeldExclusively() {
            return getState() == 1; // 判断锁是否被当前线程独占
        }
    }

    // 持有一个 Sync 实例
    private final Sync sync = new Sync();

    // 加锁方法
    public void lock() {
        sync.acquire(1); // 使用 AQS 提供的 acquire 方法
    }

    // 尝试加锁方法
    public boolean tryLock() {
        return sync.tryAcquire(1); // 尝试获取锁
    }

    // 解锁方法
    public void unlock() {
        sync.release(1); // 使用 AQS 提供的 release 方法
    }

    // 判断当前锁是否被占用
    public boolean isLocked() {
        return sync.isHeldExclusively();
    }

    public static void main(String[] args) throws InterruptedException {
        MyLock lock = new MyLock();

        Runnable task = () -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " 获取锁");
                Thread.sleep(1000); // 模拟业务操作
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(Thread.currentThread().getName() + " 释放锁");
                lock.unlock();
            }
        };

        Thread t1 = new Thread(task, "线程1");
        Thread t2 = new Thread(task, "线程2");

        t1.start();
        Thread.sleep(500);
        System.out.println("lock锁是否被占用："+lock.isLocked());
        t2.start();
    }
}
